#include "sise.h"

#ifdef __cplusplus
extern "C" {
#endif

//#include <stdio.h>

char sise_nullify(char* pBuf, unsigned int size)
{
	unsigned int i;
	
	for(i = 0; i < size; ++i) {
		pBuf[i] = 0;
	}
	
	return 0;
}

char sise_is_big_endian()
{
   short word = 0x4321;
   
   if((*(char *)& word) != 0x21)
     return 1;
   else 
     return 0;
}

char sise_hexchar2char(char hex)
{
	return (
		((hex >= '0') && (hex <= '9'))
		?
		hex - '0'
		:
		(
			((hex >= 'A') && (hex <= 'F'))
			?
			hex - 'A' + 10
			:
			(
				((hex >= 'a') && (hex <= 'f'))
				?
				hex - 'a' + 10
				:
				-1
			)
		)
	);
}

int sise_hex2bin_auto(char* pHex, char* pBin, unsigned int sizeBin)
{
	unsigned int i;
	unsigned char c1, c2;
	
	for(i = 0; i < sizeBin; ++i) {
		c1 = sise_hexchar2char((char)*pHex);
		if(c1 < 0) {
			return -1;
		}
		
		c2 = sise_hexchar2char((char)*(pHex + 1));
		if(c2 < 0) {
			return -1;
		}
		
		*pBin = c1*16 + c2;
		
		pHex += 2;
		pBin += 1;
	}
	
	return 0;
}

int sise_bin2hex_auto(char* pHex, char* pBin, unsigned int sizeBin)
{
	unsigned int i;
	unsigned char ch, c1, c2;
	
	for(i = 0; i < sizeBin; ++i) {
		ch = (char)*pBin;
		
		c1 = ch / 16;
		c2 = ch % 16;
		
		*pHex = SISE_HEXA[c1];
		*(pHex + 1) = SISE_HEXA[c2];
		
		pHex += 2;
		pBin += 1;
	}
	
	return 0;
}

int sise_hex2bin(char* pHex, char* pBin, unsigned int sizeBin)
{
	unsigned int i;
	unsigned char c1, c2;
	
	for(i = 0; i < sizeBin; ++i) {
		c1 = sise_hexchar2char((char)pHex[2*i]);
		if(c1 < 0) {
			return -1;
		}
		//printf("c1 = %d\n", c1);
		
		c2 = sise_hexchar2char((char)(pHex[2*i + 1]));
		if(c2 < 0) {
			return -1;
		}
		//printf("c2 = %d\n", c2);
		
		pBin[i] = c1*16 + c2;
		//printf("pBin[i] = %d\n\n", pBin[i]);
		
		//pHex += 2;
		//pBin += 1;
	}
	
	return 0;
}

int sise_bin2hex(char* pHex, char* pBin, unsigned int sizeBin)
{
	unsigned int i;
	unsigned char ch, c1, c2;
	
	for(i = 0; i < sizeBin; ++i) {
		ch = (char)pBin[i];
		//printf("pBin[i] = %d\n", pBin[i]);
		//printf("ch = %d\n", ch);
		
		c1 = ch / 16;
		c2 = ch % 16;
		
		//printf("c1 = %d\n", c1);
		//printf("c2 = %d\n\n", c2);
		
		pHex[2*i] = SISE_HEXA[c1];
		pHex[2*i + 1] = SISE_HEXA[c2];
		
		//pHex += 2;
		//pBin += 1;
	}
	
	return 0;
}

int sise_bin2short(char* pBin, short* pVar)
{
	short tmp;
	
	tmp = pBin[0];
	tmp = tmp*256 + (unsigned char)pBin[1];
	
	*pVar = tmp;
	
	return 0;
}

int sise_bin2int(char* pBin, int* pVar)
{
	const int FIELD_SIZE = sizeof(int);
	union {
		unsigned char _char[FIELD_SIZE];
		int temp;
	} aux;
	int i;
	
	if( sise_is_big_endian() ) {
		for(i = 0; i < FIELD_SIZE; ++i) {
			aux._char[i] = pBin[i];
		}
	} else {
		for(i = 0; i < FIELD_SIZE; ++i) {
			aux._char[i] = pBin[FIELD_SIZE - i - 1];
		}
	}
	
	*pVar = aux.temp;
	
	return 0;
}

int sise_bin2long(char* pBin, long* pVar)
{
	const int FIELD_SIZE = sizeof(long);
	union {
		unsigned char _char[FIELD_SIZE];
		long temp;
	} aux;
	int i;
	
	if( sise_is_big_endian() ) {
		for(i = 0; i < FIELD_SIZE; ++i) {
			aux._char[i] = pBin[i];
		}
	} else {
		for(i = 0; i < FIELD_SIZE; ++i) {
			aux._char[i] = pBin[FIELD_SIZE - i - 1];
		}
	}
	
	*pVar = aux.temp;
	
	return 0;
}

int sise_bin2float(char* pBin, float* pVar)
{
	const int FIELD_SIZE = sizeof(float);
	union {
		unsigned char _char[FIELD_SIZE];
		float temp;
	} aux;
	int i;
	
	if( sise_is_big_endian() ) {
		for(i = 0; i < FIELD_SIZE; ++i) {
			aux._char[i] = pBin[i];
		}
	} else {
		for(i = 0; i < FIELD_SIZE; ++i) {
			aux._char[i] = pBin[FIELD_SIZE - i - 1];
		}
	}
	
	*pVar = aux.temp;
	
	return 0;
}

int sise_bin2double(char* pBin, double* pVar)
{
	const int FIELD_SIZE = sizeof(double);
	union {
		unsigned char _char[FIELD_SIZE];
		double temp;
	} aux;
	int i;
	
	if( sise_is_big_endian() ) {
		for(i = 0; i < FIELD_SIZE; ++i) {
			aux._char[i] = pBin[i];
		}
	} else {
		for(i = 0; i < FIELD_SIZE; ++i) {
			aux._char[i] = pBin[FIELD_SIZE - i - 1];
		}
	}
	
	*pVar = aux.temp;
	
	return 0;
}

int sise_var2bin_short(char* pBin, short* pVar)
{
	short tmp;
	
	tmp = *pVar;
	pBin[0] = tmp / 256;
	pBin[1] = tmp % 256;
	
	return 0;
}

int sise_var2bin_int(char* pBin, int* pVar)
{
	const int FIELD_SIZE = sizeof(int);
	union {
		unsigned char _char[FIELD_SIZE];
		int temp;
	} aux;
	int i;
	
	aux.temp = *pVar;
	
	if( sise_is_big_endian() ) {
		for(i = 0; i < FIELD_SIZE; ++i) {
			pBin[i] = aux._char[i];
		}
	} else {
		for(i = 0; i < FIELD_SIZE; ++i) {
			pBin[FIELD_SIZE - i - 1] = aux._char[i];
		}
	}
	
	return 0;
}

int sise_var2bin_long(char* pBin, long* pVar)
{
	const int FIELD_SIZE = sizeof(long);
	union {
		unsigned char _char[FIELD_SIZE];
		long temp;
	} aux;
	int i;
	
	aux.temp = *pVar;
	
	if( sise_is_big_endian() ) {
		for(i = 0; i < FIELD_SIZE; ++i) {
			pBin[i] = aux._char[i];
		}
	} else {
		for(i = 0; i < FIELD_SIZE; ++i) {
			pBin[FIELD_SIZE - i - 1] = aux._char[i];
		}
	}
	
	return 0;
}

int sise_var2bin_float(char* pBin, float* pVar)
{
	const int FIELD_SIZE = sizeof(float);
	union {
		unsigned char _char[FIELD_SIZE];
		float temp;
	} aux;
	int i;
	
	aux.temp = *pVar;
	
	if( sise_is_big_endian() ) {
		for(i = 0; i < FIELD_SIZE; ++i) {
			pBin[i] = aux._char[i];
		}
	} else {
		for(i = 0; i < FIELD_SIZE; ++i) {
			pBin[FIELD_SIZE - i - 1] = aux._char[i];
		}
	}
	
	return 0;
}

int sise_var2bin_double(char* pBin, double* pVar)
{
	const int FIELD_SIZE = sizeof(double);
	union {
		unsigned char _char[FIELD_SIZE];
		double temp;
	} aux;
	int i;
	
	aux.temp = *pVar;
	
	if( sise_is_big_endian() ) {
		for(i = 0; i < FIELD_SIZE; ++i) {
			pBin[i] = aux._char[i];
		}
	} else {
		for(i = 0; i < FIELD_SIZE; ++i) {
			pBin[FIELD_SIZE - i - 1] = aux._char[i];
		}
	}
	
	return 0;
}

#ifdef __cplusplus
}
#endif
